package com.xmy.cultivate.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmy.cultivate.entity.OrderDetail;
import com.xmy.cultivate.entity.views.ResApplyGather;
import com.xmy.cultivate.mapper.OrderDetailMapper;
import com.xmy.cultivate.service.IOrderDetailService;
import com.xmy.cultivate.util.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单报名信息 前端控制器
 * </p>
 *
 * @author min
 * @since 2022-08-01
 */
@RestController
@RequestMapping("/api/orderDetail")
@Scope("prototype")
public class OrderDetailController extends BaseController{


    @Autowired
    IOrderDetailService iOrderDetailService;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired //如果给redis中保存数据会使用默认的序列化机制，导致redis中保存的对象不可视
    RedisTemplate<Object, Object> redisTemplate;




    @PutMapping("/stopCourse/{orderDetailId}")
    public Result stopCourse(@PathVariable(value = "orderDetailId") Long orderDetailId){


        boolean rs;
        return new Result(Code.OK,"","操作成功");
    }

    /**
     * 收入日报表
     * @return
     */
    @GetMapping("incomeDayStatement")
    public Result incomeDayStatement(){
        return new Result(Code.OK,"","操作成功");
    }
    

    @GetMapping("/applyGather")
    public Result applyGather(@RequestParam Map reMap,
                              @RequestParam(value = "lessonType", defaultValue = "1",required = false) String lessonType){
        Integer pageNum = StringUtils.isEmpty((String)reMap.get("pageNum")) ? 1 : Integer.valueOf((String)reMap.get("pageNum"));
        Integer pageSize = StringUtils.isEmpty((String)reMap.get("pageSize")) ? 10: Integer.valueOf((String)reMap.get("pageSize"));

        String schoolId = (String) reMap.get("schoolId");

        String subjectsId = (String) reMap.get("subjectsId");

        String quarterNum = (String) reMap.get("quarterNum");

        IPage<OrderDetail> iPage = new Page<>(pageNum,pageSize);
        QueryWrapper<OrderDetail> orderDetailQueryWrapper = new QueryWrapper<>();

        orderDetailQueryWrapper.eq("deleted",0);
        orderDetailQueryWrapper.ne("status",2);
        orderDetailQueryWrapper.eq("school_id",schoolId);
        orderDetailQueryWrapper.eq("subjects_id",subjectsId);
        orderDetailQueryWrapper.eq("quarter_num",quarterNum);
        orderDetailQueryWrapper.orderByDesc("created_at");
        orderDetailQueryWrapper.eq(StringUtils.isNotBlank(lessonType),"lesson_type",lessonType);

        List<String> groupByList = new ArrayList<>();
        groupByList.add("school_id");
        groupByList.add("subjects_id");
        groupByList.add("student_id");
        orderDetailQueryWrapper.groupBy(groupByList);
        iOrderDetailService.applyGatherForPage(orderDetailQueryWrapper,iPage);
        return new Result(Code.OK,new PageResult(iPage.getRecords(),iPage.getTotal(),iPage.getPages()));
    }

    /**
     * 导出
     * @param reMap
     * @return
     */
    @GetMapping("/applyGatherExport")
    public void applyGatherExport(@RequestParam Map reMap) throws IOException {

        String schoolId = (String) reMap.get("schoolId");

        String subjectsId = (String) reMap.get("subjectsId");

        String quarterNum = (String) reMap.get("quarterNum");

        QueryWrapper<OrderDetail> orderDetailQueryWrapper = new QueryWrapper<>();

        orderDetailQueryWrapper.eq("deleted",0);
        orderDetailQueryWrapper.ne("status",2);
        orderDetailQueryWrapper.eq("school_id",schoolId);
        orderDetailQueryWrapper.eq("subjects_id",subjectsId);
        orderDetailQueryWrapper.eq("quarter_num",quarterNum);
        orderDetailQueryWrapper.orderByDesc("created_at");


        List<String> groupByList = new ArrayList<>();
        groupByList.add("school_id");
        groupByList.add("subjects_id");
        groupByList.add("student_id");
        orderDetailQueryWrapper.groupBy(groupByList);

        List<ResApplyGather> resApplyGatherList = iOrderDetailService.applyGatherList(orderDetailQueryWrapper);

        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet();
        String [] titles = "校区,科目,学员,总已收学费,总课时,已上课时,剩余课时".split(",");

        //处理标题
        Row row = sheet.createRow(0);
        int titleIndex=0;
        for (String title : titles) {
            Cell cell = row.createCell(titleIndex++);
            cell.setCellValue(title);
        }

        Cell cell= null;
        int rowIndex = 1;
        for (ResApplyGather resApplyGather:resApplyGatherList){
            row =sheet.createRow(rowIndex++);
            cell =row.createCell(0);
            cell.setCellValue(resApplyGather.getSchoolName());
            cell =row.createCell(1);
            cell.setCellValue(resApplyGather.getSubjectsName());
            cell =row.createCell(2);
            cell.setCellValue(resApplyGather.getStudentName());
            cell =row.createCell(3);
            cell.setCellValue(resApplyGather.getAllSolidPrice().toString());
            cell =row.createCell(4);
            cell.setCellValue(resApplyGather.getAllCourseHouse());
            cell =row.createCell(5);
            cell.setCellValue(resApplyGather.getAllUseCourseHouse()==null ? "0" : resApplyGather.getAllUseCourseHouse().toString());
            cell =row.createCell(6);
            cell.setCellValue(resApplyGather.getResidueCourseHouse());
        }
        //3.完成下载
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        wb.write(os);
        new DownloadUtils().download(os,response,"报读汇总.xlsx");
    }

    /**
     * 学员总人数
     *
     * @return
     */
    @RequiresPermissions(value = "dashboard:index")
    @GetMapping("/countStudents")
    public Result countStudents(){
        List<OrderDetail> orderDetails = iOrderDetailService.countStudentsBySubject();
        List orderDetailList=new ArrayList<>();
        HashMap hashMap = new HashMap<>();
        for(OrderDetail orderDetail : orderDetails){
            hashMap.put("oneSubject", orderDetail.getOneSubject());
            hashMap.put("twoSubjects", orderDetail.getTwoSubjects());
            hashMap.put("threeSubjects", orderDetail.getThreeSubjects());
            hashMap.put("numStudents", orderDetail.getNumStudents());
        }

        orderDetailList.add(hashMap);
        return new Result(Code.GET_OK,orderDetailList,Code.GET_OK_MSG);
    }

    /**
     * 科目转换数据
     *
     * @return
     */
    @RequiresPermissions(value = "dashboard:index")
    @GetMapping("/subjectChange")
    public Result subjectChange(){

        List orderDetailList=new ArrayList<>();
        String redisIdKey = "subjectChange::1";
        Object o = redisTemplate.opsForValue().get(redisIdKey);
        redisTemplate.opsForValue().set(redisIdKey,null);
        if(Objects.isNull(o)){
            List<OrderDetail> orderDetails = orderDetailMapper.subjectChange();
            for(OrderDetail orderDetail : orderDetails){
                HashMap hashMap = new HashMap<>();
                hashMap.put("previousSubjects", orderDetail.getPreviousSubject());
                hashMap.put("currentSubjects", orderDetail.getCurrentSubject());
                hashMap.put("transferCount", orderDetail.getTransferCount());
                orderDetailList.add(hashMap);
                redisTemplate.opsForValue().set(redisIdKey,orderDetailList,3, TimeUnit.HOURS);
            }
        }else {
            orderDetailList = (List<OrderDetail>)o;
        }
        return new Result(Code.GET_OK,orderDetailList,Code.GET_OK_MSG);
    }

    /**
     * 多期/科报名数据
     *
     * @return
     */
    @RequiresPermissions(value = "dashboard:index")
    @GetMapping("/simultaneously")
    public Result simultaneously(@RequestParam Map reMap){
        String quarterNum = (String) reMap.get("quarterNum");
        String yearPart = (String) reMap.get("yearPart");

        String redisIdKey = "simultaneously::"+yearPart+"-"+quarterNum;
        Object o = redisTemplate.opsForValue().get(redisIdKey);
        List orderDetailList=new ArrayList<>();

        if (Objects.isNull(o)){
            HashMap hashMap = new HashMap<>();
            DecimalFormat df = new DecimalFormat("#.##");

            //同时报两期
            QueryWrapper wrapper = new QueryWrapper<>();
            wrapper.eq(StringUtils.isNotBlank(yearPart),"year_part",yearPart);
            wrapper.eq(StringUtils.isNotBlank(quarterNum),"quarter_num",quarterNum);
            wrapper.eq("lesson_type",1);
            wrapper.ge("all_course_count",90);
            wrapper.inSql("student_id","( SELECT student_id FROM enroll_info ) ");//新生，有邀约试听成交的学生
            wrapper.groupBy("quarter_num");
            hashMap.put("simultaneouslyCountStudent",orderDetailMapper.simultaneouslyCountStudent(wrapper));

            wrapper.clear();

            //同期报名人数
            wrapper.eq(StringUtils.isNotBlank(yearPart),"year_part",yearPart);
            wrapper.eq(StringUtils.isNotBlank(quarterNum),"quarter_num",quarterNum);
            wrapper.eq("lesson_type",1);
            wrapper.inSql("student_id","( SELECT student_id FROM enroll_info ) ");
            wrapper.groupBy("quarter_num");
            hashMap.put("countStudent",orderDetailMapper.simultaneouslyCountStudent(wrapper));

            List<OrderDetail> orderDetails =orderDetailMapper.simultaneouslyCountStudentsBySubject(quarterNum,yearPart);
            for(OrderDetail orderDetail : orderDetails){
                //同时报两科
                hashMap.put("twoSubjects", orderDetail.getTwoSubjects());
                //同时报三科
                hashMap.put("threeSubjects", orderDetail.getThreeSubjects());
            }

            // 同时报两科的数量除以同期报名总人数
            double firstCalculation = 0.0;
            if (hashMap.containsKey("twoSubjects") && hashMap.containsKey("countStudent") && (int) hashMap.get("countStudent") != 0) {
                firstCalculation = ((Integer) hashMap.get("twoSubjects")).doubleValue() / (int) hashMap.get("countStudent");
            }
            hashMap.put("firstCalculation", df.format(firstCalculation * 100) + "%");

            // 同时报三科的数量除以同期报名总人数
            double secondCalculation = 0.0;
            if (hashMap.containsKey("threeSubjects") && hashMap.containsKey("countStudent") && (int) hashMap.get("countStudent") != 0) {
                secondCalculation = ((Integer) hashMap.get("threeSubjects")).doubleValue() / (int) hashMap.get("countStudent");
            }
            hashMap.put("secondCalculation", df.format(secondCalculation * 100) + "%");

            // （同时报两科加同时报三科的数量）的和除以同期报名总人数
            double thirdCalculation = 0.0;
            if (hashMap.containsKey("countStudent") && (int) hashMap.get("countStudent") != 0) {
                thirdCalculation = ((double)((Integer) hashMap.get("twoSubjects")) + (double)((Integer) hashMap.get("threeSubjects"))) / (int) hashMap.get("countStudent");
            }
            hashMap.put("thirdCalculation", df.format(thirdCalculation * 100) + "%");

            // 同时报两期的数量除以同期报名总人数
            double fourthCalculation = 0.0;
            if (hashMap.containsKey("simultaneouslyCountStudent") && hashMap.containsKey("countStudent") && hashMap.get("countStudent") != null && hashMap.get("simultaneouslyCountStudent") != null && (int) hashMap.get("countStudent") != 0) {
                fourthCalculation = ((Integer) hashMap.get("simultaneouslyCountStudent")).doubleValue() / (int) hashMap.get("countStudent");
            }
            hashMap.put("fourthCalculation", df.format(fourthCalculation * 100) + "%");

            orderDetailList.add(hashMap);
            redisTemplate.opsForValue().set(redisIdKey,orderDetailList,3, TimeUnit.HOURS);
        }else {
            orderDetailList =  (List<OrderDetail>)o;
        }

        return new Result(Code.GET_OK,orderDetailList,Code.GET_OK_MSG);
    }

    /**
     * 待转校学员列表显示
     *
     * @param reMap
     * @return
     */
    @GetMapping("/changeSchoolStudents")
    public Result changeSchoolStudents(@RequestParam Map reMap){
        // ！！因为易浩老师说不传分页获取全部，所以我就把分页默认值改成了-1，这样就可以获取全部了
        Integer pageNum = StringUtils.isEmpty((String)reMap.get("pageNum")) ? -1 : Integer.valueOf((String)reMap.get("pageNum"));
        Integer pageSize = StringUtils.isEmpty((String)reMap.get("pageSize")) ? -1: Integer.valueOf((String)reMap.get("pageSize"));
        IPage<OrderDetail> iPage = new Page<>(pageNum,pageSize);

        String yearPart = (String) reMap.get("yearPart");
        String quarterNum = (String) reMap.get("quarterNum");
        String schoolId = (String) reMap.get("schoolId");
        String yearClassId = (String) reMap.get("yearClassId");
        String subjectsId = (String) reMap.get("subjectsId");
        String teacherId = (String) reMap.get("teacherId");
        String gradeId = (String) reMap.get("gradeId");
        String studentName = (String) reMap.get("studentName");

        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("o.lesson_type", 1);
        wrapper.gt("o.residue_course_count", 0);
        wrapper.eq("o.year_part", yearPart);
        wrapper.eq("o.quarter_num", quarterNum);
        wrapper.eq(StringUtils.isNotBlank(yearClassId), "o.year_class_id", yearClassId);
        wrapper.eq(StringUtils.isNotBlank(schoolId), "o.school_id", schoolId);
        wrapper.eq(StringUtils.isNotBlank(subjectsId), "o.subjects_id", subjectsId);
        wrapper.eq(StringUtils.isNotBlank(gradeId), "sg.grade_id", gradeId);
        wrapper.eq(StringUtils.isNotBlank(teacherId), "g.teacher_id", teacherId);
        wrapper.like(StringUtils.isNotBlank(studentName), "s.`name`", studentName);
        wrapper.notInSql("o.student_id", "SELECT change_school_detail.student_id FROM change_school_detail LEFT JOIN change_school ON change_school_detail.change_school_id = change_school.id WHERE change_school.`status` = 0 AND change_school_detail.subjects_id = o.subjects_id AND change_school.year_part =" + yearPart + " AND change_school.quarter_num =" + quarterNum);
        wrapper.groupBy("student_id,subjects_id,school_id");
        wrapper.having("residue_course_count > 0 ");

        orderDetailMapper.changeSchoolStudents(iPage,wrapper);

        List dataList = new ArrayList<>();
        for(OrderDetail orderDetail:iPage.getRecords()){
            HashMap hashMap = new HashMap<>();
            hashMap.put("id",orderDetail.getId());
            hashMap.put("studentId",orderDetail.getStudentId());
            hashMap.put("studentName",orderDetail.getStudentName());
            hashMap.put("yearClassId",orderDetail.getYearClassId());
            hashMap.put("subjectsId",orderDetail.getSubjectsId());
            hashMap.put("teacherId",orderDetail.getTeacherId());
            hashMap.put("teacherName",orderDetail.getTeacherName());
            hashMap.put("gradeId",orderDetail.getGradeId());
            hashMap.put("gradeName",orderDetail.getGradeName());
            hashMap.put("readingStatus",orderDetail.getReadingStatus().getValue());
            hashMap.put("schoolId",orderDetail.getSchoolId());
            hashMap.put("schoolName",orderDetail.getSchoolName());
            dataList.add(hashMap);
        }

        return new Result(Code.OK,new PageResult(dataList,iPage.getTotal(),iPage.getPages()));
    }

    /**
     * 待转校科目列表显示
     *
     * @param reMap
     * @return
     */
    @GetMapping("/changeSchoolSubjects")
    public Result changeSchoolSubjects(@RequestParam Map reMap){
        Integer pageNum = StringUtils.isEmpty((String)reMap.get("pageNum")) ? 1 : Integer.valueOf((String)reMap.get("pageNum"));
        Integer pageSize = StringUtils.isEmpty((String)reMap.get("pageSize")) ? 10: Integer.valueOf((String)reMap.get("pageSize"));
        IPage<OrderDetail> iPage = new Page<>(pageNum,pageSize);

        String yearPart = (String) reMap.get("yearPart");
        String quarterNum = (String) reMap.get("quarterNum");
        String schoolId = (String) reMap.get("schoolId");
        String yearClassId = (String) reMap.get("yearClassId");
        String subjectsId = (String) reMap.get("subjectsId");

        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.select("id,school_id,subjects_id,year_class_id,getSchoolName(school_id) AS school_name");
        wrapper.eq("quarter_num",quarterNum);
        wrapper.eq("year_part",yearPart);
        wrapper.eq(StringUtils.isNotBlank(schoolId),"school_id",schoolId);
        wrapper.eq(StringUtils.isNotBlank(yearClassId),"year_class_id",yearClassId);
        wrapper.eq(StringUtils.isNotBlank(subjectsId),"subjects_id",subjectsId);
        wrapper.eq("lesson_type",1);
        wrapper.groupBy("school_id,subjects_id,year_class_id");
        wrapper.orderByAsc("school_id,subjects_id,year_class_id");

       iOrderDetailService.page(iPage,wrapper);

        List list = new ArrayList<>();
        for(OrderDetail orderDetail:iPage.getRecords()){
            HashMap hashMap = new HashMap<>();
            hashMap.put("id",orderDetail.getId());
            hashMap.put("yearClassId",orderDetail.getYearClassId());
            hashMap.put("yearClassName", CommonUtil.getYearClassNameForId(orderDetail.getYearClassId()));
            hashMap.put("subjectsId",orderDetail.getSubjectsId());
            hashMap.put("subjectsName",CommonUtil.getSubjectsNameForId(Math.toIntExact(orderDetail.getSubjectsId())));
            hashMap.put("schoolId",orderDetail.getSchoolId());
            hashMap.put("schoolName",orderDetail.getSchoolName());
            list.add(hashMap);
        }

        return new Result(Code.OK,new PageResult(list,iPage.getTotal(),iPage.getPages()));
    }
}
